﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FinModel
{
    public sealed class YieldCurve
    {
        /// <summary>
        /// year vs. continuous compounding rate
        /// </summary>
        private List<Tuple<double, double>> _yields = new List<Tuple<double, double>>();

        public YieldCurve(params Tuple<double, double>[] yields)
        {
            _yields.Add(new Tuple<double, double>(0f, 0f));
            _yields.AddRange(yields.OrderBy(p => p.Item1));

            Interpolation();
        }
        public double this[double year] 
        { 
            get 
            {
                double min = double.MaxValue;
                int minpos = -1;
                for (int i = 0; i < _yields.Count; ++i)
                {
                    if (min > Math.Abs(_yields[i].Item1 - year))
                    {
                        min = Math.Abs(_yields[i].Item1 - year);
                        minpos = i;
                    }
                }
                return _yields[minpos].Item2;
            } 
        }
        public double[] Years { get { return _yields.Select(p => p.Item1).ToArray(); } }
        public double[] Rates { get { return _yields.Select(p => p.Item2).ToArray(); } }

        private void Interpolation()
        {
            double x = 0f;
            double y = 0f;
            double x1 = 0f;
            double x2 = 0f;
            double y1 = 0f;
            double y2 = 0f;

            for (int i = 0; i < _yields.Count() - 1; )
            {
                x1 = _yields[i].Item1;
                y1 = _yields[i].Item2;
                x2 = _yields[i + 1].Item1;
                y2 = _yields[i + 1].Item2;
                x = (x1 + x2) / 2;
                if ((x2 - x1) >= 1f)
                {
                    y = y1 + (x - x1) / (x2 - x1) * (y2 - y1);
                    _yields.Insert(i + 1, new Tuple<double, double>(x, y));
                }
                i++;
            }
        }
    }
}
